perm filename MSSNGR.SAI[PNT,HE] blob
sn#469111 filedate 1979-08-27 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00006 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 ENTRY
C00004 00003 ! PEEK, POKE, PEEKARRAY, POKEARRAY
C00012 00004
C00014 00005 ! check elf status and communication
C00017 00006 ! alinit
C00019 ENDMK
C⊗;
ENTRY;
BEGIN
DEFINE $MSSNGR=TRUE;
REQUIRE "HEADER.SAI" SOURCE_FILE;
DEFINE WAKEUP = '0,
ASLEEP = '0,
AWAKE = '100,
LISTEN = '1,
LISTENING = '101,
WORK = '2,
WORKING = '102,
DONEWORKING= '103,
GAVEUP = '104,
GOSLEEP = '3;
DEFINE MAP_OFFSET = "'320000"; ! Converts virtual addresses to physical ones;
DEFINE NOTB10 = "'160000"; ! The notebox from 11 to the 10 (byte address);
DEFINE NOTB11 = "'160020"; ! The notebox from 10 to the 11 (byte address);
! DEFINE OUTTST = "OUTSTR";
DEFINE OUTTST = "! ";
INTEGER ARRAY NOTBOX[1:8];
DEFINE PCDBUF="NOTBOX[2]",
INTBUF="NOTBOX[3]",
FPBUF="NOTBOX[4]",
INTPTR="NOTBOX[5]",
FPPTR="NOTBOX[6]",
INTSIZ="NOTBOX[7]",
FPSIZ="NOTBOX[8]";
INTEGER ELFCHAN; ! Channel number for I/O to ELF;
PROCEDURE COMERR
(STRING MESSG;RECORD_POINTER(ANY_CLASS) CONTXT (NULL_RECORD));
! Non-fatal warnings;
BEGIN
USERERR(0,1,"HAH! "&MESSG);
END;
INTEGER ARRAY TMPBUF[1:1000];
! PEEK, POKE, PEEKARRAY, POKEARRAY;
DEFINE MTAPE = "'072000";
INTEGER PROCEDURE PEEK(INTEGER ADR);
BEGIN "peek" ! Returns the ELF word at unibus address ADR;
DEFINE PEEK = "'002000000000";
LABEL PEK1, PEKMTA, PEK3, PEK4, PEK5;
INTEGER ANS, ADR1;
ADR1 ← ADR;
START_CODE;
MOVE 1,ADR1 ; ! Prepare MTAPE data in PEK1;
LSH 1,-1 ;
HRRM 1,PEK1 ;
MOVE 1,ELFCHAN ; ! Prepare MTAPE in PEKMTA;
LSH 1,5 ;
ADDI 1,MTAPE ;
HRLM 1,PEKMTA ;
PEKMTA:
PEK1 ; ! This will become MTAPE ELFCHAN,PEK1;
JRST PEK3 ; ! Error;
JRST PEK4 ; ! OK;
PEK1:
PEEK ;
PEK5:
0 ;
PEK3:
SETOM PEK5 ; ! Error result;
PEK4:
MOVE 1,PEK5 ;
MOVEM 1,ANS ;
END;
IF ANS = -1 THEN COMERR("Couldn't peek at ELF");
RETURN(ANS);
END "peek";
PROCEDURE POKE(INTEGER ADR, CONTENTS);
BEGIN "poke" ! Stores CONTENTS at unibus address ADR;
DEFINE POKE = "'003000000000";
LABEL POK1, POKMTA, POK3, POK4, POK5;
INTEGER ANS, ADR1, CNTS;
ADR1 ← ADR;
CNTS ← CONTENTS;
START_CODE;
MOVE 1,ADR1 ; ! Prepare MTAPE data in POK1;
LSH 1,-1 ;
HRRM 1,POK1 ;
MOVE 1,ELFCHAN ; ! Prepare MTAPE in POKMTA;
LSH 1,5 ;
ADDI 1,MTAPE ;
HRLM 1,POKMTA ;
MOVE 1,CNTS ;
MOVEM 1,POK5 ;
POKMTA:
POK1 ; ! This will become MTAPE ELFCHAN,POK1;
JRST POK3 ; ! Error;
JRST POK4 ; ! OK;
POK1:
POKE ;
POK5:
0 ;
POK3:
SETOM POK5 ; ! Error result;
POK4:
MOVE 1,POK5 ;
MOVEM 1,ANS ;
END;
IF ANS = -1 THEN COMERR("Couldn't poke at ELF");
RETURN;
END "poke";
PROCEDURE POKEARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS);
BEGIN "pokearray" ! Sends the CONTENTS[1:LTH] to unibus address ADR
and higher;
INTEGER ADR1, LTH1, CNTS;
LABEL SND1, SND4, SNDUST, SNDIOW, SNDOUT;
DEFINE USETO = "'075000";
DEFINE OUT = "'057000";
OUTTST(CRLF&"POKING AT "&CVOS(ADR));
ADR1 ← ADR + MAP_OFFSET;
CNTS ← LOCATION(CONTENTS[1]);
LTH1 ← LTH;
START_CODE;
MOVE 1,ADR1 ; ! Prepare USETO data in SND1;
LSH 1,-1 ;
ADDI 1,'400000 ;
HRRM 1,SND1 ;
MOVE 1,ELFCHAN ; ! Prepare USETO in SNDUST;
LSH 1,5 ;
ADDI 1,USETO ;
HRLM 1,SNDUST ;
SNDUST:
SND1 ; ! This will become USETO ELFCHAN,SND1;
JRST SND4 ; ! OK;
SND1:
'400000000000 ; ! one word transfer, don't grab unibus;
SNDIOW:
0 ; ! Will be IOWD [LTH,CNTS];
SND4:
MOVN 1,LTH1 ; ! Prepare IOWD in SNDIOW;
HRLZM 1,SNDIOW ;
MOVE 1,CNTS ;
SUBI 1,1 ;
HRRM 1,SNDIOW ;
MOVE 1,ELFCHAN ; ! Prepare OUT in SNDOUT;
LSH 1,5 ;
ADDI 1,OUT ;
HRLM 1,SNDOUT ;
SNDOUT:
SNDIOW ; ! This will become OUT ELFCHAN,SNDIOW;
SETZ 1, ; ! Success return;
MOVEM 1,ADR1 ; ! Failure return;
END;
IF ADR1 ≠ 0 THEN COMERR("POKEARRAY failed");
RETURN;
END "pokearray";
PROCEDURE PEEKARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; BOOLEAN EXTSGNBIT(FALSE));
BEGIN "peekarray" ! Gets the CONTENTS[1:LTH] from unibus address ADR
and higher;
! default mode is for nonextension of sign bit;
INTEGER ADR1, LTH1, CNTS,EXTND1;
LABEL GET1, GET4, GETUST, GETIOW, GETIN;
DEFINE USETI = "'074000";
DEFINE IN = "'056000";
DEFINE EXTEND = "'400004000000";
DEFINE NOEXTEND = "'400000000000";
OUTTST(CRLF&"PEEKING AT "&CVOS(ADR));
ADR1 ← ADR + MAP_OFFSET;
CNTS ← LOCATION(CONTENTS[1]);
LTH1 ← LTH;
IF EXTSGNBIT THEN EXTND1←EXTEND ELSE EXTND1←NOEXTEND;
START_CODE;
MOVE 1,EXTND1 ; ! Prepare the correct transfer code ;
MOVEM 1,GET1 ; ! put into the right location ;
MOVE 1,ADR1 ; ! Prepare USETI data in GET1;
LSH 1,-1 ;
ADDI 1,'400000 ;
HRRM 1,GET1 ;
MOVE 1,ELFCHAN ; ! Prepare USETI in GETUST;
LSH 1,5 ;
ADDI 1,USETI ;
HRLM 1,GETUST ;
GETUST:
GET1 ; ! This will become USETI ELFCHAN,GET1;
JRST GET4 ; ! OK;
GET1:
'400000000000 ; ! ONE WORD TRANSFER, DON'T GRAB UNIBUS;
GETIOW:
0 ; ! Will be IOWD [LTH,CNTS];
GET4:
MOVN 1,LTH1 ; ! Prepare IOWD in GETIOW;
HRLZM 1,GETIOW ;
MOVE 1,CNTS ;
SUBI 1,1 ;
HRRM 1,GETIOW ;
MOVE 1,ELFCHAN ; ! Prepare IN in GETIN;
LSH 1,5 ;
ADDI 1,IN ;
HRLM 1,GETIN ;
GETIN:
GETIOW ; ! This will become IN ELFCHAN,GETIOW;
SETZ 1, ; ! Success return;
MOVEM 1,ADR1 ; ! Failure return;
END;
IF ADR1 ≠ 0 THEN COMERR("PEEKARRAY failed");
RETURN;
END "peekarray";
! check elf status and communication ;
INTEGER PROCEDURE ELFSTATUS;
BEGIN
INTEGER I,STATUS;
CHKESC_I;
POKE(NOTB11,WAKEUP);
FOR I←1 STEP 1 UNTIL 10 DO
BEGIN
CALL(0,"SLEEP");
STATUS←PEEK(NOTB11);
IF STATUS≠ASLEEP THEN RETURN(STATUS)
END;
RETURN(STATUS);
END;
BOOLEAN ELF_ASLEEP_PRINTED;
INTEGER PROCEDURE LISTENELF;
BEGIN
INTEGER STATUS;
$ELFABORTED←FALSE;
STATUS←ELFSTATUS;
IF STATUS≠ASLEEP THEN RETURN(STATUS);
IF NOT ELF_ASLEEP_PRINTED THEN
BEGIN
PRINT("ELF is asleep, I will keep trying to wake it",CRLF,
" till you type esc_I to abort",CRLF);
ELF_ASLEEP_PRINTED←TRUE;
END;
DO BEGIN
STATUS←ELFSTATUS;
CHKESC_I;
END UNTIL STATUS≠ASLEEP;
RETURN(STATUS);
END;
INTERNAL PROCEDURE EVAL(RPTR(EXPR$) EE);
BEGIN
INTEGER I,INTSIZE,REALSIZE;
$PCDMAX←$PCDMAX MAX EXPR$:#BODY[EE];
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
POKE(NOTB10,LISTEN);
ELF_ASLEEP_PRINTED←FALSE; ! make sure print out error ;
DO I←LISTENELF UNTIL I=LISTENING;
POKEARRAY(PCDBUF,EXPR$:#BODY[EE],EXPR$:BODY[EE]);
POKE(NOTB10,WORK);
DO IF (I←LISTENELF)=GAVEUP
THEN BEGIN POKE(NOTB10,GOSLEEP);
ERROR("abandoned this instruction midway");
END UNTIL I=DONEWORKING;
PEEKARRAY(NOTB11-MAP_OFFSET,8,NOTBOX);
IF $INTSIZ←INTSIZ THEN PEEKARRAY(INTBUF,INTSIZ,$INBUF,TRUE);
IF $FPSIZ←FPSIZ THEN
BEGIN
PEEKARRAY(FPBUF,2*FPSIZ,TMPBUF);
FOR I←1 STEP 1 UNTIL FPSIZ DO
$FPBUF[I]←RFVAL(TMPBUF[I*2-1],TMPBUF[I*2]);
END;
POKE(NOTB10,GOSLEEP);
$FPPTR←$INTPTR←0;
$FPMAX←$FPMAX MAX $FPSIZ;
$INTMAX←$INTMAX MAX $INTSIZ;
END;
! alinit;
INTERNAL PROCEDURE ALINIT;
BEGIN "init"
INTEGER COUNT, BRCHAR, EOF, FLAG;
OWN BOOLEAN ONCE; comment INITIALIZE(ONCE←FALSE);
INTEGER I;
! Initialize the ELF for output;
! '400 on in mode word and EOF←1 to take silent return if not available;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
EOF←1;
OPEN(ELFCHAN←GETCHAN,"ELF",'417,0,0,COUNT,BRCHAR,EOF);
IF EOF THEN
BEGIN PRINT("ELF is not available... I will just not do any i/o to ELF
"); $ELFUNAVAILABLE←TRUE; RETURN; END;
ELF_ASLEEP_PRINTED←FALSE;
DO I←LISTENELF UNTIL I=AWAKE;
PEEKARRAY(NOTB11-MAP_OFFSET,8,NOTBOX);
END "init";
END;